RDMA/hns: RDMA/hns: Assign rq head pointer when enable rq record db
authorLijun Ou <oulijun@huawei.com>
Sat, 12 Jan 2019 10:36:29 +0000 (18:36 +0800)
committerSalvatore Bonaccorso <carnil@debian.org>
Thu, 18 Jul 2019 22:23:17 +0000 (23:23 +0100)
When flush cqe, it needs to get the pointer of rq and sq from db address
space of user and update it into qp context by modified qp. if rq does not
exist, it will not get the value from db address space of user.

Signed-off-by: Lijun Ou <oulijun@huawei.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Gbp-Pq: Topic bugfix/arm64/huawei-taishan
Gbp-Pq: Name 0031-RDMA-hns-RDMA-hns-Assign-rq-head-pointer-when-enable.patch

drivers/infiniband/hw/hns/hns_roce_qp.c

index de1676e258282fd6a1411c0325d333484be46afe..b3ad35310925469afbabb1079ca045757253222e 100644 (file)
@@ -652,6 +652,10 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
                                dev_err(dev, "rq record doorbell map failed!\n");
                                goto err_sq_dbmap;
                        }
+
+                       /* indicate kernel supports rq record db */
+                       resp.cap_flags |= HNS_ROCE_SUPPORT_RQ_RECORD_DB;
+                       hr_qp->rdb_en = 1;
                }
        } else {
                if (init_attr->create_flags &
@@ -760,16 +764,11 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
        else
                hr_qp->doorbell_qpn = cpu_to_le64(hr_qp->qpn);
 
-       if (ib_pd->uobject && (udata->outlen >= sizeof(resp)) &&
-               (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB)) {
-
-               /* indicate kernel supports rq record db */
-               resp.cap_flags |= HNS_ROCE_SUPPORT_RQ_RECORD_DB;
-               ret = ib_copy_to_udata(udata, &resp, sizeof(resp));
+       if (udata) {
+               ret = ib_copy_to_udata(udata, &resp,
+                                      min(udata->outlen, sizeof(resp)));
                if (ret)
                        goto err_qp;
-
-               hr_qp->rdb_en = 1;
        }
        hr_qp->event = hns_roce_ib_qp_event;
 
@@ -946,7 +945,9 @@ int hns_roce_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
            (attr_mask & IB_QP_STATE) && new_state == IB_QPS_ERR) {
                if (hr_qp->sdb_en == 1) {
                        hr_qp->sq.head = *(int *)(hr_qp->sdb.virt_addr);
-                       hr_qp->rq.head = *(int *)(hr_qp->rdb.virt_addr);
+
+                       if (hr_qp->rdb_en == 1)
+                               hr_qp->rq.head = *(int *)(hr_qp->rdb.virt_addr);
                } else {
                        dev_warn(dev, "flush cqe is not supported in userspace!\n");
                        goto out;